package com.mtf.redis.demo;

import org.luaj.vm2.ast.Str;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Set;

/**
 * 基于Redis实现限流
 */
@Component
public class LimitRequestDemo {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final int LIMIT_REQUEST = 60;
    private static final String REDIS_KEY = "limit_request";
    private static final int EXPIRE_TIME = 60;
    //时间窗口
    private static final int TIME_WINDOW = 60;

    /**
     * 方案一：Redis计数器实现接口限流
     */
    public Boolean limitRequestByIncr(){
        Long increment = stringRedisTemplate.opsForValue().increment(REDIS_KEY);

        if(increment == 1){
            increment = stringRedisTemplate.opsForValue().increment(REDIS_KEY, EXPIRE_TIME);
        }
        if (increment > LIMIT_REQUEST){
            //请求放行
            return false;
        }else {
            //请求拦截
            return true;
        }
    }

    /**
     * 方案二：Redis的zset集合和时间窗口实现接口限流
     */
    public Boolean limitRequestByZset(){
        //获取当前时间戳
        long currentTimeMillis = System.currentTimeMillis();
        Set<String> range = stringRedisTemplate.opsForZSet().range(REDIS_KEY, currentTimeMillis - TIME_WINDOW, currentTimeMillis);
        if (range.size() > LIMIT_REQUEST){
            return false;
        }else {
            stringRedisTemplate.opsForZSet().add(REDIS_KEY, String.valueOf(currentTimeMillis),currentTimeMillis);
            return true;
        }
    }

    /**
     * 方案三：令牌桶 通过定时任务初始化list集合中的“令牌”
     */

}
